import "./base.css";
import "./index.css";
import { useState, useEffect } from "react";
import TodoItem from "./TodoItem";
import TodoFooter from "./TodoFooter";
import {
  ENTER_KEY,
  ALL_TODOS,
  ACTIVE_TODOS,
  COMPLETED_TODOS,
} from "@/Utils/constants";
import { observer } from "mobx-react";
import useStores from "@/Hooks/useStores";

const Todos = () => {
  const hash = window.location.hash.replace('#/', '')
  const todoStore = useStores("todoStore");
  const [newTodo, setNewTodo] = useState<string>("");
  const [nowShowing, setNowShowing] = useState<string>(hash && hash !== ALL_TODOS ? hash : ALL_TODOS);
  const [editing, setEditing] = useState<string | null>(null);

  const handleNewTodoKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (
    e
  ) => {
    if (e.keyCode !== ENTER_KEY) {
      return;
    }
    e.preventDefault();

    const val = newTodo.trim();
    if (val) {
      todoStore.addTodo(val);
      setNewTodo("");
    }
  };

  const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
    setNewTodo(e.target.value);
  };

  const toggleAll: React.ChangeEventHandler<HTMLInputElement> = (e) => {
    const checked = e.target.checked;
    todoStore.toggleAll(checked);
  };

  const toggle = (todoToToggle: ITodoItem) => {
    todoStore.toggle(todoToToggle);
  };

  const destroy = (todo: ITodoItem) => {
    todoStore.destroy(todo);
  };

  const edit = (todo: ITodoItem) => {
    setEditing(todo.id);
  };

  const save = (todoToSave: ITodoItem, text: string) => {
    todoStore.save(todoToSave, text);
    setEditing(null);
  };

  const cancel = () => {
    setEditing(null);
  };

  const clearCompleted = () => {
    todoStore.clearCompleted();
  };

  const clickShowing = (value: string) => {
    switch(value) {
      case 'active':
        setNowShowing(ACTIVE_TODOS)
        return
      case 'completed':
        setNowShowing(COMPLETED_TODOS)
        return
      default:
        // all
        setNowShowing(ALL_TODOS)
        return
    }
  }

  let main = null;
  let footer = null;

  const activeTodoCount = todoStore.todos.reduce(function (
    accum: number,
    todo: ITodoItem
  ) {
    return todo.completed ? accum : accum + 1;
  },
  0);

  const completedCount = todoStore.todos.length - activeTodoCount;

  const shownTodos = todoStore.todos.filter((todo: ITodoItem) => {
    switch (nowShowing) {
      case ACTIVE_TODOS:
        return !todo.completed;
      case COMPLETED_TODOS:
        return todo.completed;
      default:
        return true;
    }
  });

  const todoItems = shownTodos.map((todo: ITodoItem) => {
    return (
      <TodoItem
        key={todo.id}
        todo={todo}
        editing={editing === todo.id}
        onToggle={() => toggle(todo)}
        onDestroy={() => destroy(todo)}
        onEdit={() => edit(todo)}
        onSave={save.bind(this, todo)}
        onCancel={() => cancel()}
      />
    );
  });

  if (activeTodoCount || completedCount) {
    footer = (
      <TodoFooter
        count={activeTodoCount}
        completedCount={completedCount}
        nowShowing={nowShowing}
        onClearCompleted={clearCompleted}
        onClickShowing={clickShowing}
      />
    );
  }

  if (todoStore.todos.length) {
    main = (
      <section className="main">
        <input
          id="toggle-all"
          className="toggle-all"
          type="checkbox"
          onChange={toggleAll}
          checked={activeTodoCount === 0}
        />
        <label htmlFor="toggle-all" />
        <ul className="todo-list">{todoItems}</ul>
      </section>
    );
  }

  return (
    <div className="todoapp">
      <header className="header">
        <h1>todos</h1>
        <input
          className="new-todo"
          placeholder="What needs to be done?"
          value={newTodo}
          onKeyDown={handleNewTodoKeyDown}
          onChange={handleChange}
          autoFocus={true}
        />
      </header>
      {main}
      {footer}
    </div>
  );
};

export default observer(Todos);
